package cn.zcj.studytest.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {


    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
        redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);

        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }

    @Bean("rateLimitUseIncr")
    public DefaultRedisScript<Long> rateLimitUseIncr() {
        return new DefaultRedisScript<>(getScript(), Long.class);
    }

    @Bean("minuteLimit")
    public DefaultRedisScript<Long> getMinuteLimit() {
        return new DefaultRedisScript<>(minuteLimit(), Long.class);
    }


    private String getScript() {
        return "local current=0\n" +
                "current = redis.call(\"incr\",KEYS[1])\n" +
                "if tonumber(current) == 1 then\n" +
                "    redis.call(\"PEXPIRE\",KEYS[1],1100)\n" +
                "end\n" +
                "return current";
    }

    private String minuteLimit() {
        return "local current=0\n" +
                "current = redis.call(\"incr\",KEYS[1])\n" +
                "if tonumber(current) == 1 then\n" +
                "    redis.call(\"EXPIRE\",KEYS[1],60)\n" +
                "end\n" +
                "return current";
    }

    public static String incrAndTime(Integer seconds) {
        return "local current=0\n" +
                "current = redis.call(\"incr\",KEYS[1])\n" +
                "if tonumber(current) == 1 then\n" +
                "    redis.call(\"EXPIRE\",KEYS[1], " + seconds + ")\n" +
                "end\n" +
                "return current";
    }
}
